﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Text;
using wojilu.Reflection;

namespace wojilu.Data
{
    public interface ISqliteHelper
    {
        Type GetSqliteCommandType();
        Type GetSqliteConnectionType();

        IDbConnection GetSqliteConnection(String connectionString);
        IDbCommand GetSqliteCommand();
        DbDataAdapter GetSqliteDataAdapter(Object cmd);
        IDbDataParameter GetSqliteParameter(String parameterName, Object parameterValue);
    }
    public class SqliteHelperLoader
    {
        private static ISqliteHelper _sqliteHelper = loadSqliteHelper();

        private static ISqliteHelper loadSqliteHelper()
        {

            String code = makeCode();

            Dictionary<String, Assembly> asmList = getSqliteAsmList();
            Assembly asm = CodeDomHelper.CompileCode(code, asmList, null);

            return asm.CreateInstance("wojilu.Data.SqliteHelper") as ISqliteHelper;
        }

        public static ISqliteHelper GetHelper()
        {
            return _sqliteHelper;
        }

        private static Dictionary<String, Assembly> getSqliteAsmList()
        {

            Assembly sqliteAssembly = null;
            try
            {
                sqliteAssembly = Assembly.Load("System.Data.SQLite");
            }
            catch
            {
                throw new Exception("缺少 System.Data.SQLite.dll 文件。请从 lib 目录复制到 bin 中");
            }

            Dictionary<String, Assembly> ret = new Dictionary<String, Assembly>();
            foreach (KeyValuePair<String, Assembly> kv in ObjectContext.Instance.AssemblyList)
            {
                ret.Add(kv.Key, kv.Value);
            }

            ret.Add("System.Data.SQLite", sqliteAssembly);

            return ret;
        }

        private static string makeCode()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("using System;");
            sb.AppendLine("using System.Text;");
            sb.AppendLine("using System.Data;");
            sb.AppendLine("using System.Data.Common;");
            sb.AppendLine("using System.Data.SQLite;");

            sb.AppendLine("namespace wojilu.Data {");
            sb.Append(@"public class SqliteHelper : ISqliteHelper {

        public Type GetSqliteCommandType() {
            return typeof( System.Data.SQLite.SQLiteCommand );
        }

        public Type GetSqliteConnectionType() {
            return typeof( System.Data.SQLite.SQLiteConnection );
        }

        public IDbCommand GetSqliteCommand() {
            return new System.Data.SQLite.SQLiteCommand();
        }

        public IDbConnection GetSqliteConnection( String connectionString ) {
            return new System.Data.SQLite.SQLiteConnection( connectionString );
        }

        public DbDataAdapter GetSqliteDataAdapter( Object cmd ) {
            if (cmd == null) throw new ArgumentNullException( ""cmd"" );
            return new System.Data.SQLite.SQLiteDataAdapter( cmd as SQLiteCommand );
        }

        public IDbDataParameter GetSqliteParameter( String parameterName, Object parameterValue ) {
            return new System.Data.SQLite.SQLiteParameter( parameterName, parameterValue );
        }

    }");

            sb.AppendLine("}");

            return sb.ToString();
        }

    }
}
